package com.qimu.saiyou.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qimu.saiyou.common.ErrorCode;
import com.qimu.saiyou.constant.CommonConstant;
import com.qimu.saiyou.exception.BusinessException;
import com.qimu.saiyou.exception.ThrowUtils;
import com.qimu.saiyou.mapper.ExamPaperMapper;
import com.qimu.saiyou.model.dto.exampaper.ExamPaperAddRequest;
import com.qimu.saiyou.model.dto.exampaper.ExamPaperQueryRequest;
import com.qimu.saiyou.model.dto.exampaper.ExamPaperUpdateRequest;
import com.qimu.saiyou.model.dto.paperquestion.PaperQuestionAddRequest;
import com.qimu.saiyou.model.entity.ExamPaper;
import com.qimu.saiyou.model.entity.PaperQuestion;
import com.qimu.saiyou.model.entity.Question;
import com.qimu.saiyou.service.ExamPaperService;
import com.qimu.saiyou.service.PaperQuestionService;
import com.qimu.saiyou.service.QuestionService;
import com.qimu.saiyou.utils.SqlUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: FeiXiang
 * @description 针对表【exam_paper(试卷)】的数据库操作Service实现
 * @createDate 2024-02-28 20:36:14
 */
@Service
public class ExamPaperServiceImpl extends ServiceImpl<ExamPaperMapper, ExamPaper>
        implements ExamPaperService {
    @Resource
    private PaperQuestionService paperQuestionService;
    @Resource
    private QuestionService questionService;

    @Override
    public void validExamPaper(ExamPaper examPaper, boolean add) {
        String title = examPaper.getTitle();
        Integer qualifyScore = examPaper.getQualifyScore();
        if (add) {
            ThrowUtils.throwIf(StringUtils.isBlank(title), ErrorCode.PARAMS_ERROR, "试卷名称不能为空");
            ThrowUtils.throwIf(ObjectUtils.isEmpty(qualifyScore), ErrorCode.PARAMS_ERROR, "及格分数不能为空");
        }
        if (StringUtils.isNotBlank(title) && title.trim().length() > 100) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "试卷名称过长");
        }
        if (ObjectUtils.isNotEmpty(qualifyScore) && qualifyScore <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "及格分数不能小于等于0");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public long addExamPaper(ExamPaperAddRequest examPaperAddRequest) {
        ExamPaper examPaper = new ExamPaper();
        BeanUtils.copyProperties(examPaperAddRequest, examPaper);
        this.validExamPaper(examPaper, true);
        List<PaperQuestionAddRequest> paperQuestionList = examPaperAddRequest.getPaperQuestionList();
        boolean save = this.save(examPaper);
        ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "试卷创建失败");
        if (CollUtil.isNotEmpty(paperQuestionList)) {
            List<PaperQuestion> paperQuestionArrayList = new ArrayList<>();
            for (int i = 0; i < paperQuestionList.size(); i++) {
                PaperQuestionAddRequest paperQuestionAddRequest = paperQuestionList.get(i);
                if (paperQuestionAddRequest.getScore() == null || paperQuestionAddRequest.getScore() <= 0) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "题目分值不能小于等于0");
                }
                Question question = questionService.getById(paperQuestionAddRequest.getQuestionId());
                ThrowUtils.throwIf(question == null, ErrorCode.PARAMS_ERROR, "题目不存在");
                PaperQuestion paperQuestion = new PaperQuestion();
                BeanUtils.copyProperties(paperQuestionAddRequest, paperQuestion);
                paperQuestion.setPaperId(examPaper.getId());
                paperQuestion.setQuestionId(question.getId());
                paperQuestionArrayList.add(paperQuestion);
            }
            int totalSum = paperQuestionArrayList.stream().mapToInt(PaperQuestion::getScore).sum();
            if (ObjectUtils.isNotEmpty(examPaper.getQualifyScore()) && examPaper.getQualifyScore() > totalSum) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "及格分数不能大于题目总分");
            }
            examPaper.setTotalScore(totalSum);
            this.updateById(examPaper);
            boolean saveBatch = paperQuestionService.saveBatch(paperQuestionArrayList);
            ThrowUtils.throwIf(!saveBatch, ErrorCode.OPERATION_ERROR, "试卷创建失败");
        }
        return examPaper.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteExamPaper(long id) {
        QueryWrapper<PaperQuestion> paperQuestionQueryWrapper = new QueryWrapper<>();
        paperQuestionQueryWrapper.lambda().eq(PaperQuestion::getPaperId, id);
        List<Long> longList = paperQuestionService.list(paperQuestionQueryWrapper).stream().map(PaperQuestion::getId).collect(Collectors.toList());
        boolean removeBatchByIds = paperQuestionService.removeBatchByIds(longList);
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateExamPaper(ExamPaperUpdateRequest examPaperUpdateRequest) {
        ExamPaper examPaper = new ExamPaper();
        BeanUtils.copyProperties(examPaperUpdateRequest, examPaper);
        // 参数校验
        validExamPaper(examPaper, false);
        long id = examPaperUpdateRequest.getId();
        List<PaperQuestionAddRequest> paperQuestionList = examPaperUpdateRequest.getPaperQuestionList().stream().distinct().collect(Collectors.toList());
        ThrowUtils.throwIf(CollUtil.isEmpty(paperQuestionList), ErrorCode.PARAMS_ERROR, "试题不能为空");
        // 判断是否存在
        ExamPaper oldExamPaper = this.getById(id);
        ThrowUtils.throwIf(oldExamPaper == null, ErrorCode.NOT_FOUND_ERROR);

        List<PaperQuestion> newPaperQuestionArrayList = new ArrayList<>();
        QueryWrapper<PaperQuestion> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PaperQuestion::getPaperId, examPaper.getId());
        List<PaperQuestion> paperQuestions = paperQuestionService.list(queryWrapper);
        List<Long> paperQuestionIdList = paperQuestions.stream().map(PaperQuestion::getQuestionId).collect(Collectors.toList());
        List<Long> paperIdList = paperQuestions.stream().map(PaperQuestion::getId).collect(Collectors.toList());
        for (int i = 0; i < paperQuestionList.size(); i++) {
            PaperQuestionAddRequest paperQuestionAddRequest = paperQuestionList.get(i);
            Integer score = paperQuestionAddRequest.getScore();
            if (score == null || score <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "题目分值不能小于等于0");
            }
            Long questionId = paperQuestionAddRequest.getQuestionId();
            for (PaperQuestion paperQuestion : newPaperQuestionArrayList) {
                if (paperQuestion.getQuestionId().equals(questionId)) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "题目重复!");
                }
            }
            if (paperQuestionIdList.contains(questionId)) {
                PaperQuestion paperQuestion = paperQuestions.stream().filter(p -> p.getQuestionId().equals(questionId)).findFirst().get();
                paperQuestion.setScore(score);
                paperQuestion.setId(null);
                newPaperQuestionArrayList.add(paperQuestion);
                continue;
            }
            Question question = questionService.getById(questionId);
            ThrowUtils.throwIf(question == null, ErrorCode.PARAMS_ERROR, "题目不存在");
            PaperQuestion paperQuestion = new PaperQuestion();
            BeanUtils.copyProperties(paperQuestionAddRequest, paperQuestion);
            paperQuestion.setPaperId(examPaper.getId());
            paperQuestion.setQuestionId(question.getId());
            newPaperQuestionArrayList.add(paperQuestion);
        }
        int total = newPaperQuestionArrayList.stream().mapToInt(PaperQuestion::getScore).sum();
        if (ObjectUtils.isNotEmpty(examPaper.getQualifyScore()) && examPaper.getQualifyScore() > total) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "及格分数不能大于题目总分");
        }
        examPaper.setTotalScore(total);
        if (CollUtil.isNotEmpty(paperIdList)) {
            paperQuestionService.removeBatchByIds(paperIdList);
        }
        if (CollUtil.isNotEmpty(newPaperQuestionArrayList)) {
            paperQuestionService.saveBatch(newPaperQuestionArrayList);
        }
        return this.updateById(examPaper);
    }

    @Override
    public QueryWrapper<ExamPaper> getQueryWrapper(ExamPaperQueryRequest examPaperQueryRequest) {
        QueryWrapper<ExamPaper> queryWrapper = new QueryWrapper<>();
        if (examPaperQueryRequest == null) {
            return queryWrapper;
        }
        Long id = examPaperQueryRequest.getId();
        String searchText = examPaperQueryRequest.getSearchText();
        int current = examPaperQueryRequest.getCurrent();
        int pageSize = examPaperQueryRequest.getPageSize();
        String sortField = examPaperQueryRequest.getSortField();
        String sortOrder = examPaperQueryRequest.getSortOrder();

        // 拼接查询条件
        if (StringUtils.isNotBlank(searchText)) {
            queryWrapper.and(qw -> qw.lambda().like(ExamPaper::getTitle, searchText));
        }
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }
}




